package com.someclip.component.controlls
{
	import com.someclip.component.container.Container;
	import com.someclip.component.container.Direction;
	import com.someclip.component.core.Component;
	import com.someclip.component.interfaces.IScrollBar;
	import com.someclip.component.skins.Arrow;
	import com.someclip.component.skins.DefaultButtonSkin;
	import com.someclip.component.skins.DefaultFlatSkin;
	import com.someclip.component.skins.ThumbIcon;

	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	/**
	 * ...
	 * @author Argus
	 */
	public class ScrollBar extends Component implements IScrollBar
	{
		private var _direction:String=Direction.VERTICAL;
		private var _pageSize:Number=90;
		private var _maxPosition:Number=100;
		private var _minPosition:Number=0;
		private var _lineScrollSize:Number=1;
		private var _pageScrollSize:Number=1;
		private var _scrollPosition:Number=0;
		private var _startBtn:IconButton;
		private var _endBtn:IconButton;
		private var _thumbBtn:IconButton;
		private var _bar:Container;

		public function ScrollBar()
		{
			_startBtn=new IconButton();
			_startBtn.width=_startBtn.height=20;
			_startBtn.iconStyle=new Arrow("up");
			_endBtn=new IconButton();
			_endBtn.width=_endBtn.height=20;
			_endBtn.iconStyle=new Arrow("down");
			_thumbBtn=new IconButton();
			_thumbBtn.iconStyle=new ThumbIcon();
			_bar=new Container();
			_bar.styleLink=new DefaultFlatSkin(0x555555);
			addChild(_startBtn);
			addChild(_endBtn);
			addChild(_bar);
			addChild(_thumbBtn);
			_thumbBtn.addEventListener(MouseEvent.MOUSE_DOWN, handleThumbBtnMouseDown);
			_startBtn.addEventListener(MouseEvent.CLICK, handleStartBtnClick);
			_endBtn.addEventListener(MouseEvent.CLICK, handleEndBtnClick);
			_bar.addEventListener(MouseEvent.CLICK, handleBarClick);
			this.addEventListener(Event.ADDED_TO_STAGE, handleThisAddedToStage);
		}

		private function handleBarClick(event:MouseEvent):void
		{
			var temp:Number;
			switch (_direction)
			{
				case Direction.VERTICAL:
					temp=((_maxPosition - _minPosition) * (DisplayObject(event.currentTarget).mouseY - _bar.top)) / _bar.height;
					break;
				case Direction.HORIZONTAL:
					temp=((_maxPosition - _minPosition) * (DisplayObject(event.currentTarget).mouseX - _bar.left)) / _bar.width;
					break;
			}
			if (temp > _scrollPosition)
			{
				_scrollPosition+=_pageScrollSize;
			}
			else
			{
				_scrollPosition-=_pageScrollSize;
			}
			if (_scrollPosition > _maxPosition - _pageSize)
				_scrollPosition=_maxPosition - _pageSize;
			if (_scrollPosition <= _minPosition)
				_scrollPosition=_minPosition;
			updateBar();
		}

		private function handleEndBtnClick(e:MouseEvent):void
		{
			_scrollPosition+=_lineScrollSize;
			if (_scrollPosition > _maxPosition - _pageSize)
				_scrollPosition=_maxPosition - _pageSize;
			updateBar();
		}

		private function handleStartBtnClick(e:MouseEvent):void
		{
			_scrollPosition-=_lineScrollSize;
			if (_scrollPosition <= _minPosition)
				_scrollPosition=_minPosition;
			updateBar();
		}

		private function handleThumbBtnMouseDown(e:MouseEvent):void
		{
			switch (_direction)
			{
				case Direction.VERTICAL:
					_thumbBtn.startDrag(false, new Rectangle(_bar.x + 2, _bar.y, .05, _bar.height - _bar.height * _pageSize / (_maxPosition - _minPosition)));
					break;
				case Direction.HORIZONTAL:
					_thumbBtn.startDrag(false, new Rectangle(_bar.left, _bar.y + 2, _bar.width - _bar.width * _pageSize / (_maxPosition - _minPosition), .05));
					break;
			}
			stage.addEventListener(MouseEvent.MOUSE_MOVE, handleStageMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, handleStageMouseUp);
		}

		private function handleStageMouseMove(e:MouseEvent):void
		{
			switch (_direction)
			{
				case Direction.VERTICAL:
					_scrollPosition=((_maxPosition - _minPosition) * (_thumbBtn.y - _bar.top)) / _bar.height;
					break;
				case Direction.HORIZONTAL:
					_scrollPosition=((_maxPosition - _minPosition) * (_thumbBtn.x - _bar.left)) / _bar.width;
					break;
			}

		}


		private function handleStageMouseUp(e:MouseEvent):void
		{
			_thumbBtn.stopDrag();
			stage.removeEventListener(MouseEvent.MOUSE_UP, handleStageMouseUp);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleStageMouseMove);
		}

		private function handleThisAddedToStage(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, handleThisAddedToStage);
			updateBar();
		}

		private function updateBar():void
		{
			switch (_direction)
			{
				case Direction.VERTICAL:
					_startBtn.top=0;
					_endBtn.bottom=0;
					_bar.width=_startBtn.width;
					_bar.height=this.height - _startBtn.height - _endBtn.height;
					_bar.top=_startBtn.height;
					_thumbBtn.width=_startBtn.width - 4;
					_thumbBtn.height=_bar.height * _pageSize / (_maxPosition - _minPosition);
					_thumbBtn.y=_bar.top + _scrollPosition * _bar.height / (_maxPosition - _minPosition)
					_thumbBtn.x=2;
					break;
				case Direction.HORIZONTAL:
					_startBtn.left=0;
					_endBtn.right=0;
					_bar.height=_startBtn.height;
					_bar.width=this.width - _startBtn.width - _endBtn.width;
					_bar.left=_startBtn.width;
					_thumbBtn.height=_startBtn.height - 4;
					_thumbBtn.width=_bar.width * _pageSize / (_maxPosition - _minPosition);
					_thumbBtn.x=_bar.left + _scrollPosition * _bar.width / (_maxPosition - _minPosition);
					_thumbBtn.y=2;
					break;
			}

		}

		/* INTERFACE com.someclip.component.interfaces.ISomeScrollBar */

		public function get direction():String
		{
			return _direction;
		}

		public function set direction(value:String):void
		{
			_direction=value;
		}

		public function get pageSize():Number
		{
			return _pageSize;
		}

		public function set pageSize(value:Number):void
		{
			_pageSize=value;
		}

		public function get maxPosition():Number
		{
			return _maxPosition;
		}

		public function set maxPosition(value:Number):void
		{
			_maxPosition=value;
		}

		public function get minPosition():Number
		{
			return _minPosition;
		}

		public function set minPosition(value:Number):void
		{
			_minPosition=value;
		}

		public function get lineScrollSize():Number
		{
			return _lineScrollSize;
		}

		public function set lineScrollSize(value:Number):void
		{
			_lineScrollSize=value;
		}

		public function get pageScrollSize():Number
		{
			return _pageScrollSize;
		}

		public function set pageScrollSize(value:Number):void
		{
			_pageScrollSize=value;
		}

		public function get scrollPosition():Number
		{
			return _scrollPosition;
		}

		public function set scrollPosition(value:Number):void
		{
			_scrollPosition=value;
			updateBar();
		}

		public function get upArrowStyle():Object
		{
			return _startBtn.styleLink;
		}

		public function set upArrowStyle(value:Object):void
		{
			_startBtn.styleLink=value;
		}

		public function get downArrowStyle():Object
		{
			return _endBtn.styleLink;
		}

		public function set downArrowStyle(value:Object):void
		{
			_endBtn.styleLink=value;
		}

		public function get thumbStyle():Object
		{
			return _thumbBtn.styleLink;
		}

		public function set thumbStyle(value:Object):void
		{
			_thumbBtn.styleLink=value;
		}

		public function get barStyle():Object
		{
			return _bar.styleLink;
		}

		public function set barStyle(value:Object):void
		{
			_bar.styleLink=value;
		}
	}

}
